package services;

import java.util.Collection;
import java.util.Date;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.PaintingRepository;
import domain.Actor;
import domain.Customer;
import domain.Ownership;
import domain.Painting;
import forms.PaintingForm;


@Service
@Transactional
public class PaintingService {

	// Managed repository

	@Autowired
	private PaintingRepository paintingRepository;

	// Supporting services
	
	@Autowired
	private ActorService actorService;
	@Autowired
	private OwnershipService ownershipService;
	@Autowired
	private AuctionService auctionService;
	
	
	// Simple CRUD methods

	public Painting create() {
		return new Painting();
	}
	
	public void save(Painting painting) {
		
		if(painting.getId()==0){
			Actor customer = actorService.findByPrincipal();
			Assert.isTrue(customer instanceof Customer);			
			paintingRepository.save(painting);
			for(Ownership ownership:painting.getOwnerships())
				ownershipService.save(ownership);
		}
		else{
			checkPrincipal(painting);
		    Assert.isTrue(painting != auctionService.findActiveAuctionByPrincipal().getPainting(),"painting.commit.error.auction");
			paintingRepository.save(painting);
		}
	}

	public void modify(Painting painting) {
		checkPrincipal(painting);
		paintingRepository.save(painting);
	}


	public Painting reconstruct(PaintingForm paintingForm) {
		Painting painting = null;
		if(paintingForm.getId()!=0)
		{
			painting = paintingRepository.findOne(paintingForm.getId());
			
		}
		else{
			painting = new Painting();
			Ownership ownership = new Ownership();
			ownership.setStartDate(new Date());
			Actor customer = actorService.findByPrincipal();
			Assert.isTrue(customer instanceof Customer);
			ownership.setLegalOwner((Customer) actorService.findByPrincipal());		
			ownership.setOwnedPainting(painting);
			painting.getOwnerships().add(ownership);
		
		}
		painting.setAppraisal(paintingForm.getAppraisal());
		painting.setAuthor(paintingForm.getAuthor());
		painting.setDate(paintingForm.getDate());
		painting.setTitle(paintingForm.getTitle());
		return painting;
	}

	// Other business methods
	
	public Painting findOne(int paintingId){
		return paintingRepository.findOne(paintingId);
	}
	
	public Collection<Painting> findPaintingsByOwnerId(int ownerId){
		return paintingRepository.findPaintingsByOwnerId(ownerId);
	}
	
	public Collection<Painting> findPaintingsByPrincipal(){
		Assert.isTrue(actorService.findByPrincipal() instanceof Customer);
		return paintingRepository.findPaintingsByOwnerId(actorService.findByPrincipal().getId());
	}
	
	public Collection<Painting> findPaintingsWithoutGalleriesAndByPrincipal(){
		Assert.isTrue(actorService.findByPrincipal() instanceof Customer);
		return paintingRepository.findPaintingsWithoutGalleryAndByPrincipal(actorService.findByPrincipal().getId());
	}
	
	public Collection<Painting> findPaintingsByGalleryId(int galleryId){
		return paintingRepository.findPaintingsByGalleryId(galleryId);
	}
	
	public Collection<Painting> findPaintingWithMoreComments(){
		return paintingRepository.findPaintingWithMoreComments();
	}

	public void checkPrincipal(Painting painting)
	{
		Customer customerP = (Customer) actorService.findByPrincipal();
		Assert.isTrue(customerP instanceof Customer);
		Assert.isTrue(this.findPaintingsByPrincipal().contains(painting));
	}




	
}
